package com.example.springbooteasycode.zjrc.dns;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 * java编写一个main方法，通过DNS访问FC，输入是十六进制字符串格式“000100”，输入是转为byte[]数组，输出也是byte[]，输出转为十六进制字符串格式打印，通过socket连接。
 *
 * args入参为一个通过“-”分割：<十六进制字符串>-<端口号>-<DNS域名>
 *                        000100-5559-www.baidu.com
 *
 *
 *
 * DNS 解析结果 for www.baidu.com：
 *   IP 地址：223.109.82.212
 *   IP 地址：223.109.82.16
 *   IP 地址：2409:8c20:6:123c:0:ff:b0f6:b2d
 *   IP 地址：2409:8c20:6:1794:0:ff:b080:87f0
 *
 *
 * DNS 解析结果 for www.doubao.com：
 *   IP 地址：39.173.34.118
 *   IP 地址：39.173.34.117
 *   IP 地址：112.15.41.10
 *   IP 地址：111.1.164.33
 *   IP 地址：39.174.58.187
 *   IP 地址：39.174.58.186
 *   IP 地址：39.174.58.185
 *   IP 地址：39.173.34.116
 *   IP 地址：39.173.32.226
 *   IP 地址：39.173.32.225
 *   IP 地址：39.173.32.224
 *   IP 地址：112.15.41.11
 */
public class DNSFCClientUp {
    public static void main(String[] args) {
        // 检查输入参数数量
        if (args.length != 1) {
            System.out.println("使用方法: java DNSFCClient <十六进制字符串>-<端口号>-<DNS域名>");
            System.out.println("示例: java DNSFCClient 000100-53-fc.example.com");
            return;
        }

        // 分割参数
        String[] parts = args[0].split("-");
        if (parts.length != 3) {
            System.out.println("参数格式错误，请使用: 十六进制字符串-端口号-DNS域名");
            System.out.println("示例: 000100-53-fc.example.com");
            return;
        }

        // 解析各部分参数
        String hexInput = parts[0];
        System.out.println("输入的十六进制字符串: " + hexInput);

        int port;
        String fcDomain = parts[2];

        // 验证并转换端口号
        try {
            port = Integer.parseInt(parts[1]);
            if (port < 1 || port > 65535) {
                System.out.println("端口号必须在1-65535之间");
                return;
            }
        } catch (NumberFormatException e) {
            System.out.println("无效的端口号，请输入数字");
            return;
        }

        try {
            // 将十六进制字符串转换为byte数组
            byte[] inputBytes = hexStringToByteArray(hexInput);

            // 通过DNS解析获取FC服务器的IP地址
            InetAddress[] addresses = InetAddress.getAllByName(fcDomain);
            if (addresses.length == 0) {
                System.out.println("无法解析FC服务器域名: " + fcDomain);
                return;
            }

            System.out.println("DNS 解析结果 for " + fcDomain + "：");
            for (InetAddress addr : addresses) {
                System.out.println("  IP 地址：" + addr.getHostAddress());
            }
//
//            // 选择第一个IP地址进行连接
//            InetAddress serverAddress = addresses[0];
//            System.out.println("连接到FC服务器: " + serverAddress.getHostAddress() + ":" + port);


            // =====================只要ipv4的地址=============================
            // 过滤出所有IPv4地址
            List<InetAddress> ipv4Addresses = new ArrayList<>();
            for (InetAddress addr : addresses) {
                if (addr instanceof Inet4Address) {  // 判断是否为IPv4地址
                    ipv4Addresses.add(addr);
                }
            }

            // 检查是否有可用的IPv4地址
            if (ipv4Addresses.isEmpty()) {
                System.out.println("未找到该域名对应的IPv4地址");
                return;
            }

            // 选择第一个IPv4地址进行连接
            InetAddress serverAddress = ipv4Addresses.get(0);
            System.out.println("使用IPv4地址连接: " + serverAddress.getHostAddress() + ":" + port);

            // 创建Socket连接
            try (Socket socket = new Socket(serverAddress, port);
                 DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                 DataInputStream in = new DataInputStream(socket.getInputStream())) {

                // 发送数据
                out.write(inputBytes);
                out.flush();
                System.out.println("发送的数据 (十六进制): " + hexInput);

                // 接收响应（根据实际情况调整缓冲区大小）
                byte[] buffer = new byte[1024];
                int bytesRead = in.read(buffer);

                if (bytesRead > 0) {
                    // 截取实际接收到的数据
                    byte[] responseBytes = new byte[bytesRead];
                    System.arraycopy(buffer, 0, responseBytes, 0, bytesRead);

                    // 将响应转换为十六进制字符串并打印
                    String hexOutput = byteArrayToHexString(responseBytes);
                    System.out.println("接收的响应 (十六进制): " + hexOutput);
                } else {
                    System.out.println("未接收到任何数据");
                }
            }

        } catch (UnknownHostException e) {
            System.err.println("无法解析主机: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("网络通信错误: " + e.getMessage());
        } catch (IllegalArgumentException e) {
            System.err.println("参数错误: " + e.getMessage());
        }
    }

    /**
     * 将十六进制字符串转换为byte数组
     */
    public static byte[] hexStringToByteArray(String s) {
        if (s == null || s.length() % 2 != 0) {
            throw new IllegalArgumentException("无效的十六进制字符串，长度必须为偶数");
        }

        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }

    /**
     * 将byte数组转换为十六进制字符串
     */
    public static String byteArrayToHexString(byte[] bytes) {
        if (bytes == null) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }
}

